package com.kma.summer2012.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.kma.summer2012.client.constants.ConstantsPresenter;
import com.kma.summer2012.client.events.ShowPreloaderEvent;
import com.kma.summer2012.client.events.authorization.AuthentificationEvent;
import com.kma.summer2012.client.events.authorization.ConfirmPasswordEvent;
import com.kma.summer2012.client.events.authorization.LoginEvent;
import com.kma.summer2012.client.events.authorization.PasswordRecoveryEvent;
import com.kma.summer2012.client.events.engineer.CloseRequestEvent;
import com.kma.summer2012.client.events.engineer.EngineerShowRequestEvent;
import com.kma.summer2012.client.events.engineer.ViewMapEvent;
import com.kma.summer2012.client.events.manager.*;
import com.kma.summer2012.client.events.operator.EditPageEvent;
import com.kma.summer2012.client.events.operator.OperatorShowRequestEvent;
import com.kma.summer2012.client.events.reject.RejectRequestEvent;
import com.kma.summer2012.client.events.reject.SuccessfulRejectEvent;
import com.kma.summer2012.client.events.request.CreateRequestEvent;
import com.kma.summer2012.client.events.request.ExportRequestEvent;
import com.kma.summer2012.client.events.request.ImportRequestEvent;
import com.kma.summer2012.client.events.request.MainPageEvent;
import com.kma.summer2012.client.presenters.Presenter;
import com.kma.summer2012.client.presenters.header.HeaderPresenter;
import com.kma.summer2012.client.services.session.CrumbsSessionService;
import com.kma.summer2012.client.services.user.CrumbsUserService;
import com.kma.summer2012.client.styles.style2.Recources;
import com.kma.summer2012.client.view.PreloaderView;
import com.kma.summer2012.client.view.header.Header;
import com.kma.summer2012.shared.model.UICrumbsRequest;
import com.kma.summer2012.shared.model.UICrumbsToolItem;
import com.kma.summer2012.shared.model.UICrumbsUser;
import com.kma.summer2012.shared.model.UICrumbsWorkItem;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//import com.kma.summer2012.client.events.reject.SuccessfulRejectEvent;
//import com.kma.summer2012.client.events.manager.AddWorkEvent;
//import com.kma.summer2012.client.events.manager.ManageWorksEvent;

public class AppController implements ValueChangeHandler<String> {

    //private Storage storage=Storage.getLocalStorageIfSupported();
    private HeaderPresenter header;
    private HasWidgets container;
    private UICrumbsUser user;

    public static ConstantsPresenter c;           //TODO (facepalm) field Naming !!!!!

    public AppController() {
        bind();
        useConstants();
    }

    private void bind() {
        History.addValueChangeHandler(this);

        CrumbsEventBus.getInstance().addHandler(LoginEvent.getType(),
                new LoginEvent.LoginEventHandler() {
                    public void onLogin(LoginEvent event) {
                        doLogin();
                    }
                });
        CrumbsEventBus.getInstance().addHandler(PasswordRecoveryEvent.getType(),
                new PasswordRecoveryEvent.PasswordRecoveryEventHandler() {
                    public void onPasswordRecovery(PasswordRecoveryEvent event) {
                        doPasswordRecovery();
                    }
                });
        CrumbsEventBus.getInstance().addHandler(ConfirmPasswordEvent.getType(), new ConfirmPasswordEvent.ConfirmPasswordEventHandler() {
            @Override
            public void OnConfirmPassword(ConfirmPasswordEvent event) {
                doConfirmPassword();
            }
        });
        CrumbsEventBus.getInstance().addHandler(MainPageEvent.getType(),
                new MainPageEvent.MainPageEventHandler() {

                    @Override
                    public void onMainPage(MainPageEvent event) {
                        doMainPage();
                    }
                });
        CrumbsEventBus.getInstance().addHandler(EditPageEvent.getType(),
                new EditPageEvent.EditPageEventHandler() {

                    @Override
                    public void onEditPageEvent(EditPageEvent event, UICrumbsRequest request) {
                        doEditRequest(request);
                    }

                   /* @Override
                    public void onShowPage(EditPageEvent event, UICrumbsRequest request) {
                        doShowRequest(request);
                    }
                       */
                });
        CrumbsEventBus.getInstance().addHandler(EditPageEventManager.getType(),
                new EditPageEventManager.EditPageEventManagerHandler() {

                    @Override
                    public void onEditPageEvent(EditPageEventManager event, UICrumbsRequest request) {
                        doEditRequestManager(request);
                    }
                });
        CrumbsEventBus.getInstance().addHandler(OperatorShowRequestEvent.getType(),
                new OperatorShowRequestEvent.OperatorRequestEventHandler() {

                    @Override
                    public void onOperatorRequestEvent(OperatorShowRequestEvent event, UICrumbsRequest request) {
                        doShowOperatorRequest(request);
                    }

                });
        CrumbsEventBus.getInstance().addHandler(ShowRequestManager.getType(),
                new ShowRequestManager.ShowRequestManagerHandler() {

                    @Override
                    public void onShowPageEvent(ShowRequestManager event, UICrumbsRequest request) {
                        doShowManagerRequest(request);
                    }

                });
        CrumbsEventBus.getInstance().addHandler(EngineerShowRequestEvent.getType(),
                new EngineerShowRequestEvent.ManagerShowRequestEventHandler() {

                    @Override
                    public void onEngineerShowRequestEvent(EngineerShowRequestEvent event, UICrumbsRequest request) {
                        doShowEngineerRequest(request);
                    }

                });
        CrumbsEventBus.getInstance().addHandler(AuthentificationEvent.getType(),
                new AuthentificationEvent.AuthentificationEventHandler() {
                    @Override
                    public void onAuthentification(AuthentificationEvent event) {
                        doAuthentification(event.getUser());
                    }
                });

        CrumbsEventBus.getInstance().addHandler(ManageToolsEvent.getType(), new ManageToolsEvent.ManageToolsEventHandler() {
            @Override
            public void onManageTools(ManageToolsEvent event) {
                doManageTools();
            }
        });
        CrumbsEventBus.getInstance().addHandler(AddToolEvent.getType(), new AddToolEvent.AddToolEventHandler() {
            @Override
            public void onAddTool(AddToolEvent event) {
                doAddTool(event.getUiTool());
            }
        });

        CrumbsEventBus.getInstance().addHandler(AddWorkCategoryEvent.getType(), new AddWorkCategoryEvent.AddWorkCategoryEventHandler() {
            @Override
            public void OnAddWorkCategory(AddWorkCategoryEvent event) {
                doAddWorkCategoryEvent(event.getUiWork());
            }
        });
        CrumbsEventBus.getInstance().addHandler(EditWorkCategoryEvent.getType(), new EditWorkCategoryEvent.EditWorkCategoryEventHandler() {
            @Override
            public void OnEditWorkCategory(EditWorkCategoryEvent event) {
                doEditWorkCategoryEvent(event.getUiWork());
            }
        });
        CrumbsEventBus.getInstance().addHandler(AddWorkEvent.getType(), new AddWorkEvent.AddWorkEventHandler() {
            @Override
            public void OnAddWork(AddWorkEvent event) {
                doAddWork(event.getUiWork());
            }
        });
        CrumbsEventBus.getInstance().addHandler(EditToolEvent.getType(), new EditToolEvent.EditToolEventHandler() {
            @Override
            public void onEditTool(EditToolEvent event) {
                doEditTool(event.getUiTool());
            }
        });

        CrumbsEventBus.getInstance().addHandler(EditWorkEvent.getType(), new EditWorkEvent.EditWorkEventHandler() {
            @Override
            public void OnEditWork(EditWorkEvent event) {
                doEditWork(event.getUiWork());
            }
        });

        CrumbsEventBus.getInstance().addHandler(ManageWorksEvent.getType(), new ManageWorksEvent.ManageWorksEventHandler() {
            @Override
            public void onManageWorks(ManageWorksEvent event) {
                doManageWorks();
            }
        });


        CrumbsEventBus.getInstance().addHandler(SuccessfulRejectEvent.getType(), new SuccessfulRejectEvent.successfulRejectEventHandler() {
            @Override
            public void OnReject(SuccessfulRejectEvent event) {
                doSuccesfullReject();
            }
        });

        CrumbsEventBus.getInstance().addHandler(RejectRequestEvent.getType(), new RejectRequestEvent.RejectRequestEventHandler() {
            @Override
            public void OnReject(RejectRequestEvent event) {
                doReject(event.getRequest());
            }
        });

        CrumbsEventBus.getInstance().addHandler(CloseRequestEvent.getType(), new CloseRequestEvent.CloseRequestEventHandler() {
            @Override
            public void OnCloseRequest(CloseRequestEvent event) {
                doClose(event.getRequest());
            }
        });
        CrumbsEventBus.getInstance().addHandler(CreateRequestEvent.getType(), new CreateRequestEvent.CreateRequestEventHandler() {
            @Override
            public void onCreateRequest() {
                doCreateRequest();
            }
        });
        CrumbsEventBus.getInstance().addHandler(ImportRequestEvent.getType(), new ImportRequestEvent.ImportRequestEventHandler() {
            @Override
            public void onImportRequest() {
                doImportRequest();
            }
        });

        CrumbsEventBus.getInstance().addHandler(ViewMapEvent.getType(), new ViewMapEvent.ViewMapEventHandler() {

            @Override
            public void onViewMap(ViewMapEvent event) {
                doViewMap();
            }
        });
        CrumbsEventBus.getInstance().addHandler(AssignForManagerEvent.getType(), new AssignForManagerEvent.AssignForManagerEventHandler() {
            @Override
            public void onAssignEvent(AssignForManagerEvent event, int requestID) {
                doAssign(requestID);
            }
        });


        CrumbsEventBus.getInstance().addHandler(ExportRequestEvent.getType(), new ExportRequestEvent.ExportRequestEventHandler() {
            @Override
            public void onExportRequest(List<UICrumbsRequest> requests) {
                AppController.this.doExport(requests);
            }
        });

        CrumbsEventBus.getInstance().addHandler(ShowPreloaderEvent.getType(), new ShowPreloaderEvent.ShowPreloaderEventHandler() {
            @Override
            public void onShowPreloader(ShowPreloaderEvent event) {
                showPreloader();
            }
        });
    }

    private void doEditWorkCategoryEvent(UICrumbsWorkItem uiWork) {
        CrumbsSessionService.App.getInstance().setParameterWorkItem(c.EDIT_CATEGORY(), uiWork, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.EDIT_CATEGORY());
            }
        });
    }

    private void doAddWorkCategoryEvent(UICrumbsWorkItem uiWork) {
        CrumbsSessionService.App.getInstance().setParameterWorkItem(c.EDIT_CATEGORY(), uiWork, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.ADD_CATEGORY());
            }
        });
    }

    private void doExport(List<UICrumbsRequest> requests) {
        if (requests != null && requests.size() > 0) {
            //FormPanel formPanel = this.getExportFormPanel(requests); //todo apache poi. export from server does not return outputstream
            FormPanel formPanel = ExportManager.getInstance().go(requests);
            FocusPanel focusPanel = new FocusPanel();
            focusPanel.add(formPanel);
            ArrayList<HasClickHandlers> list = new ArrayList<HasClickHandlers>();
            list.add(focusPanel);
            DialogBox box = DialogBoxFactory.createMessageBox("Are you sure, you want to export?", "Export", list);
            box.center();
            box.show();
        }
    }

    private FormPanel getExportFormPanel(List<UICrumbsRequest> requests){
         final FormPanel formPanel = new FormPanel();
         formPanel.setAction(GWT.getModuleBaseURL() + "CrumbsExport");
         formPanel.setEncoding(FormPanel.ENCODING_URLENCODED);
         formPanel.setMethod(FormPanel.METHOD_POST);

        VerticalPanel vPanel = new VerticalPanel();

        for (UICrumbsRequest request:requests){
            Hidden hidden = new Hidden("requestId",String.valueOf(request.getId()));
            vPanel.add(hidden);
        }
        vPanel.add(new Button("Submit",new ClickHandler() {
            @Override
            public void onClick(ClickEvent clickEvent) {
                formPanel.submit();
            }
        }));
        formPanel.add(vPanel);
        return formPanel;
    }

    private void doAuthentification(UICrumbsUser user) {
        this.user = user;
        History.newItem(c.MAIN_PAGE());

    }

    private void addHeader(UICrumbsUser user) {

    }

    private void doManageTools() {
        History.newItem(c.MANAGE_TOOLS());
    }

    private void doAddTool(UICrumbsToolItem uiTool) {
        CrumbsSessionService.App.getInstance().setParameterTool(c.TOOL_ITEM(), uiTool, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.ADD_TOOL());
            }
        });
    }

    private void doEditTool(UICrumbsToolItem uiTool) {
        CrumbsSessionService.App.getInstance().setParameterTool(c.TOOL_ITEM(), uiTool, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.EDIT_TOOL());
            }
        });
    }

    private void doImportRequest() {
        History.newItem(c.IMPORT_REQUEST());
    }

    private void doCreateRequest() {
        History.newItem(c.CREATE_REQUEST());
    }

    private void doSuccesfullReject() {
        History.newItem(c.SUCCESSFULL_REJECT());
    }


    private void doConfirmPassword() {
        History.newItem(c.CONFIRM_PASSWORD());
    }

    private void doPasswordRecovery() {
        History.newItem(c.PASSWORD_RECOVERY());

    }

    private void doLogin() {
        RootPanel.get(c.HEADER()).clear();
        RootPanel.get(c.HEADER()).removeStyleName(Recources.INSTANCE.styles().header());
        this.container.clear();
        this.header = null;
        History.newItem(c.LOGIN());
    }

    private void doReject(UICrumbsRequest request) {
        CrumbsSessionService.App.getInstance().setParameterRequest(c.REJECT_REQUEST(), request, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.REJECT());
            }
        });

    }

    private void doClose(UICrumbsRequest request) {
        CrumbsSessionService.App.getInstance().setParameterRequest(c.CLOSE_REQUEST(), request, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.CLOSE_REQUEST());
            }
        });

    }

    private void doAddWork(UICrumbsWorkItem uiCrumbsWorkItem) {
        CrumbsSessionService.App.getInstance().setParameterWorkItem("workItem", uiCrumbsWorkItem, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.ADD_WORK());
            }
        });
    }

    private void doEditWork(UICrumbsWorkItem uiCrumbsWorkItem) {
        CrumbsSessionService.App.getInstance().setParameterWorkItem(c.WORK_ITEM(), uiCrumbsWorkItem, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.EDIT_WORK());
            }
        });
    }

    private void doManageWorks() {
        History.newItem(c.MANAGE_WORKS());
    }

    private void doMainPage() {

        History.newItem(c.MAIN_PAGE());
    }

    private void doEditRequest(UICrumbsRequest o) {
        CrumbsSessionService.App.getInstance().setParameterRequest(c.CURRENT_REQUEST(), o, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                // History.newItem(c.REJECT());
                History.newItem(c.EDIT_REQUEST_OPERATOR());
            }
        });
        /*params = o;
        UICrumbsRequest t = (UICrumbsRequest) params;
        History.newItem(c.EDIT_REQUEST_OPERATOR());    */
    }

    private void doShowOperatorRequest(UICrumbsRequest o) {

        CrumbsSessionService.App.getInstance().setParameterRequest(c.CURRENT_REQUEST(), o, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                // History.newItem(c.REJECT());
                History.newItem(c.SHOW_OPERATOR_REQUEST());
            }
        });
    /*    params = o;
        UICrumbsRequest t = (UICrumbsRequest) params;
        History.newItem(c.SHOW_OPERATOR_REQUEST());   */
    }

    private void doShowManagerRequest(UICrumbsRequest o) {

        CrumbsSessionService.App.getInstance().setParameterRequest(c.CURRENT_REQUEST(), o, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                // History.newItem(c.REJECT());
                History.newItem(c.SHOW_MANAGER_REQUEST());
            }
        });
        /*    params = o;
     UICrumbsRequest t = (UICrumbsRequest) params;
     History.newItem(c.SHOW_OPERATOR_REQUEST());   */
    }

    private void doShowEngineerRequest(UICrumbsRequest o) {
        CrumbsSessionService.App.getInstance().setParameterRequest(c.CURRENT_REQUEST(), o, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                // History.newItem(c.REJECT());
                History.newItem(c.SHOW_ENGINEER_REQUEST());
            }
        });
       /* params = o;
        UICrumbsRequest t = (UICrumbsRequest) params;
        History.newItem("showManagerRequest"); */
    }

    private void doEditRequestManager(UICrumbsRequest o) {
        CrumbsSessionService.App.getInstance().setParameterRequest(c.CURRENT_REQUEST(), o, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            @Override
            public void onSuccess(Void aVoid) {
                // History.newItem(c.REJECT());
                History.newItem(c.EDIT_REQUEST_MANAGER());
            }
        });
       /* params = o;
        UICrumbsRequest t = (UICrumbsRequest) params;
        History.newItem(c.EDIT_REQUEST_MANAGER());*/
    }

    private void doAssign(int requestId) {
        CrumbsSessionService.App.getInstance().setParameterInteger("id", requestId, new AsyncCallback<Void>() {
            @Override
            public void onFailure(Throwable throwable) {
            }

            @Override
            public void onSuccess(Void aVoid) {
                History.newItem(c.ASSIGN_PAGE());
            }
        });

    }

    private void doViewMap() {
        History.newItem(c.VIEW_MAP());
    }


    public void go(final HasWidgets container) {
        this.container = container;

        if ("".equals(History.getToken())) {
            //History.newItem("passwordChange");
            //History.newItem(c.LOGIN());
            //History.newItem("manageWorks");
            //History.newItem("testPage");
            // History.newItem(c.SUCCESSFULL_REJECT());
            History.newItem(c.MAIN_PAGE());
        } else {
            History.fireCurrentHistoryState();
        }

    }

    public void useConstants() {
        c = GWT.create(ConstantsPresenter.class);

    }

    private PreloaderView preloader = null;

    private void doOnValueChange(final String token) {
        if (!token.equals(c.LOGIN()) && !token.contains(c.CHANGE_PASSWORD()) && !token.equals(c.PASSWORD_RECOVERY()) && !token.equals("confirmChange")) {

            if (Cookies.getCookie(c.USER()) == null) {
                History.newItem(c.LOGIN());
            } else {

                CrumbsUserService.App.getInstance().getById(Integer.parseInt(Cookies.getCookie(c.USER())), new AsyncCallback<UICrumbsUser>() {
                    @Override
                    public void onFailure(Throwable throwable) {
                    }

                    @Override
                    public void onSuccess(UICrumbsUser uiCrumbsUser) {

                        if (header == null) {
                            header = new HeaderPresenter(new Header(), uiCrumbsUser);
                            //  RootPanel.get("header").addStyleName(Recources.INSTANCE.styles().classDefault());
                            header.go(RootPanel.get(c.HEADER()));
                        } else {
                            header.go(RootPanel.get(c.HEADER()));
                        }
                        Presenter presenter = HistoryFactory.getInstance().goPresenter(token);
                        if (!token.equals(c.CREATE_REQUEST())) {
                        }

                        showPreloader();
                        presenter.go(container);
                    }
                });

            }
        } else {
            if (Cookies.getCookie(c.USER()) == null) {

                Presenter presenter = HistoryFactory.getInstance().goPresenter(token);
                showPreloader();
                presenter.go(container);
            } else {
                History.newItem(c.MAIN_PAGE());
            }
        }
    }

    private void showPreloader() {
        if (preloader == null) {
            AppController.this.preloader = new PreloaderView();
        }
        container.clear();
        container.add(preloader);
    }

    @Override
    public void onValueChange(ValueChangeEvent<String> event) {
        final String token = event.getValue();
        if (this.user != null) {
            Date now = new Date();
            long nowLong = now.getTime();
            nowLong = nowLong + (1000 * 60 * 60 * 24 * 7);//seven days
            now.setTime(nowLong);
            Cookies.setCookie(c.USER(), Integer.toString(this.user.getUserId()));
            doOnValueChange(token);
            AppController.this.user = null;
        } else {
            doOnValueChange(token);
        }

    }
}
